/*
 * PathReader.cpp
 *
 *  Created on: 2009/02/05
 *      Author: Yongshik Cho
 */

#include "PathReader.h"
#include "TweenReader.h"
#include "../Exception.h"


const std::string PathReader::_NAME_TAG			= "name";
const std::string PathReader::_TYPE_TAG			= "type";
const std::string PathReader::_NODE_TAG			= "Node";
const std::string PathReader::_CLOSED_TAG		= "Closed";
const std::string PathReader::_POSITION_TAG		= "Position";
const std::string PathReader::_ROTATION_TAG		= "Rotation";
const std::string PathReader::_SCALE_TAG		= "Scale";
const std::string PathReader::_WEIGHT_TAG		= "Weight";
const std::string PathReader::_LINEAR_TAG		= "LINEAR";
const std::string PathReader::_BEZIER_TAG		= "BEZIER";
const std::string PathReader::_TRUE_TAG			= "true";
const std::string PathReader::_FALSE_TAG		= "false";
const std::string PathReader::_ANGLE_TAG		= "angle";
const std::string PathReader::_X_TAG			= "x";
const std::string PathReader::_Y_TAG			= "y";


Path* PathReader::parse(TiXmlElement* element)
{
	/*
	 * 	<AltoCollision name='collision1' type='line' Closed='true'>
			<Position x=0 y=0/>
			<Rotation angle=0/>
			<Scale x=2 y=2/>

			<Point x=0 y=0/>
			<Point x=10 y=0/>
			<Point x=10 y=10/>
			<Point x=0 y=10/>
		</AltoCollision>
	 *
	 */

	char *sName, *sType, *sClosed;
	sName = (char*)element->Attribute(_NAME_TAG.c_str());
	sType = (char*)element->Attribute(_TYPE_TAG.c_str());
	sClosed = (char*)element->Attribute(_CLOSED_TAG.c_str());

	TiXmlElement* node = 0;
	node = element->FirstChildElement(_NAME_TAG.c_str()); if(node) sName = (char*)node->GetText();
	node = element->FirstChildElement(_TYPE_TAG.c_str()); if(node) sType = (char*)node->GetText();
	node = element->FirstChildElement(_CLOSED_TAG.c_str()); if(node) sClosed = (char*)node->GetText();

	Path* path = new Path();
	if(!path)
		AltoThrow(Exception::ERR_MEMORY);

	char* loopType = (char*)element->Attribute(TweenReader::_LOOPTYPE_TAG.c_str());
	node = element->FirstChildElement(TweenReader::_LOOPTYPE_TAG.c_str()); if(node) loopType = (char*)node->GetText();
	if(loopType)
	{
		if(TweenReader::_LOOPCOUNT_VALUE == loopType)
			path->setLoopType(Tweenable::LOOP_COUNT);
		else if(TweenReader::_ENDLESS_VALUE == loopType)
			path->setLoopType(Tweenable::ENDLESS);
	}
	else path->setLoopType(Tweenable::LOOP_COUNT);

	int32 loopCount = 0;
	element->Attribute(TweenReader::_LOOPCOUNT_TAG.c_str(), &loopCount);
	node = element->FirstChildElement(TweenReader::_LOOPCOUNT_TAG.c_str()); if(node) loopCount = atoi(node->GetText());

	if(sName)
#ifdef UNICODE
	{
		TCHAR wstr[512]; memset(wstr, 0, sizeof(wstr));
		::MultiByteToWideChar(CP_UTF8, 0, sName, (int32)strlen(sName), wstr, 512);
		path->setName(wstr);
	}
#else
		path->setName(sName);
#endif

	if(sType)
	{
		if(_LINEAR_TAG == sType)
		{
			path->setType(Curve2D::_LINEAR);
		}
		else if(_BEZIER_TAG == sType)
		{
			path->setType(Curve2D::_BEZIER);
		}
	}

	if(sClosed)
	{
		if(_TRUE_TAG == sClosed)
			path->setClosed(true);
		else if(_FALSE_TAG == sClosed)
			path->setClosed(false);
	}

	int32 x=0, y=0, time, weight;
	double sx=1.f, sy=1.f, angle=0.f;

	for(TiXmlElement* frame=element->FirstChildElement(_NODE_TAG.c_str());frame;frame=frame->NextSiblingElement(_NODE_TAG.c_str()))
	{
		frame->Attribute(TweenReader::_TIME_TAG.c_str(), &time);
		node = frame->FirstChildElement(TweenReader::_TIME_TAG.c_str()); if(node) time = atoi(node->GetText());
		frame->Attribute(_WEIGHT_TAG.c_str(), &weight);
		node = frame->FirstChildElement(_WEIGHT_TAG.c_str()); if(node) weight = atoi(node->GetText());

		TiXmlElement* position = frame->FirstChildElement(_POSITION_TAG.c_str());
		if(position)
		{
			position->Attribute(_X_TAG.c_str(), &x);
			node = position->FirstChildElement(_X_TAG.c_str()); if(node) x = atoi(node->GetText());
			position->Attribute(_Y_TAG.c_str(), &y);
			node = position->FirstChildElement(_Y_TAG.c_str()); if(node) y = atoi(node->GetText());
		}

		TiXmlElement* rotation = frame->FirstChildElement(_ROTATION_TAG.c_str());
		if(rotation)
		{
			rotation->Attribute(_ANGLE_TAG.c_str(), &angle);
			node = rotation->FirstChildElement(_ANGLE_TAG.c_str()); if(node) angle = atof(node->GetText());
		}

		path->addNode(PathNode(time, BezierNode(Vector2D((float)x, (float)y), (float)angle, (float)weight)));
	}

	{
		TiXmlElement* position = element->FirstChildElement(_POSITION_TAG.c_str());
		if(position)
		{
			position->Attribute(_X_TAG.c_str(), &x);
			node = position->FirstChildElement(_X_TAG.c_str()); if(node) x = atoi(node->GetText());
			position->Attribute(_Y_TAG.c_str(), &y);
			node = position->FirstChildElement(_Y_TAG.c_str()); if(node) y = atoi(node->GetText());

			path->setPosition(Vector2D((float)x, (float)y));
		}

		TiXmlElement* rotation = element->FirstChildElement(_ROTATION_TAG.c_str());
		if(rotation)
		{
			rotation->Attribute(_ANGLE_TAG.c_str(), &angle);
			node = rotation->FirstChildElement(_ANGLE_TAG.c_str()); if(node) angle = atof(node->GetText());

			path->setRotation((float)angle);
		}

		TiXmlElement* scale = element->FirstChildElement(_SCALE_TAG.c_str());
		if(scale)
		{
			scale->Attribute(_X_TAG.c_str(), &sx);
			node = scale->FirstChildElement(_X_TAG.c_str()); if(node) sx = atof(node->GetText());
			scale->Attribute(_Y_TAG.c_str(), &sy);
			node = scale->FirstChildElement(_Y_TAG.c_str()); if(node) sy = atof(node->GetText());

			path->setScale(Vector2D((float)sx, (float)sy));
		}

		//TweenReader::parseCallbacks(element, (Tweenable*)path);
	}

	return path;
}
